﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using DBMS.Models;
using DBMS.Models.DataInterfaces;
using System.IO;
using System.Windows.Forms;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using DBMS.Helpers.Application;

namespace DBMS.Data
{
    public class ColumnRepository : IColumnRepository
    {
        public Column GetColumn(int databaseId, int tableId, int columnId)
        {
            SetCurrentDirectoryToAppDir();

            Stream stream = File.Open("databases//" + databaseId.ToString() + "//" + tableId.ToString() + "//C" + columnId.ToString(), FileMode.Open);
            BinaryFormatter bformatter = new BinaryFormatter();
            Column column = (Column)bformatter.Deserialize(stream);
            stream.Close();

            return column;
        }

        public void SaveOrUpdate(int databaseId, int tableId, Column column)
        {
            SetCurrentDirectoryToAppDir();

            string[] temp =  Directory.GetFiles(Configuration.Instance.GetTableFolder(databaseId, tableId));

            int columnIndex = temp.Length + 1;
            column.Index = columnIndex;

            string colPath = "databases//" + databaseId + "//" + tableId + "//C" + column.Index;

            Stream stream = File.Open(colPath, FileMode.OpenOrCreate);
            BinaryFormatter bformatter = new BinaryFormatter();
            bformatter.Serialize(stream, column);
            stream.Close();
        }

        public IList<Column> GetAllColumnsForTable(int databaseId, int tableId)
        {
            SetCurrentDirectoryToAppDir();

            IList<Column> columns = new List<Column>();
            string[] columnFiles = Directory.GetFiles("databases//" + databaseId.ToString() + "//" + tableId.ToString());

            ValueRepository valueRepo = new ValueRepository();

            foreach (string columnFile in columnFiles)
            {
                if (columnFile.Contains("C"))
                {
                    Stream stream = File.Open(columnFile, FileMode.Open);
                    BinaryFormatter bformatter = new BinaryFormatter();
                    Column column = (Column)bformatter.Deserialize(stream);
                    stream.Close();

                    if (!column.Deleted)
                    {
                        column.Values = valueRepo.GetValuesForColumn(databaseId, tableId, column.Index);
                        columns.Add(column);
                    }
                }
            }

            return columns;
        }

        private void SetCurrentDirectoryToAppDir()
        {
            string appPath = Path.GetDirectoryName(AppDomain.CurrentDomain.BaseDirectory);
            Directory.SetCurrentDirectory(appPath);
        }


        public void SetPrimary(string databaseId, string tableId, string columnId)
        {
            IList<Column> columns = new List<Column>();
            string[] columnFiles = Directory.GetFiles("databases//" + databaseId.ToString() + "//" + tableId.ToString());

            foreach (string columnFile in columnFiles)
            {
                if (columnFile.Contains("C"))
                {
                    Stream stream = File.Open(columnFile, FileMode.Open);
                    BinaryFormatter bformatter = new BinaryFormatter();
                    Column column = (Column)bformatter.Deserialize(stream);
                    stream.Close();

                    columns.Add(column);
                }
            }

            int temp = Int32.Parse(columnId);

            foreach (Column column in columns)
            {
                if (column.Index == temp)
                {
                    column.PrimaryKey = true;
                }
                else
                {
                    column.PrimaryKey = false;
                }

                string colPath = "databases//" + databaseId + "//" + tableId + "//C" + column.Index;

                Stream stream = File.Open(colPath, FileMode.Truncate);
                BinaryFormatter bformatter = new BinaryFormatter();
                bformatter.Serialize(stream, column);
                stream.Close();
            }
        }


        public void UpdateColumn(int databaseId, int tableId, Column newColumn)
        {
            IList<Column> columns = new List<Column>();
            string[] columnFiles = Directory.GetFiles("databases//" + databaseId.ToString() + "//" + tableId.ToString());

            foreach (string columnFile in columnFiles)
            {
                if (columnFile.Contains("C"))
                {
                    Stream stream = File.Open(columnFile, FileMode.Open);
                    BinaryFormatter bformatter = new BinaryFormatter();
                    Column column = (Column)bformatter.Deserialize(stream);
                    stream.Close();

                    columns.Add(column);
                }
            }

            foreach (Column column in columns)
            {
                if (column.Index == newColumn.Index)
                {
                    column.PrimaryKey = newColumn.PrimaryKey;
                    column.Name = newColumn.Name;
                    column.Type = newColumn.Type;
                    string colPath = "databases//" + databaseId + "//" + tableId + "//C" + column.Index;

                    Stream stream = File.Open(colPath, FileMode.Truncate);
                    BinaryFormatter bformatter = new BinaryFormatter();
                    bformatter.Serialize(stream, column);
                    stream.Close();
                }
            }
        }


        public void DeleteColumn(string databaseId, string tableId, string columnId)
        {
            IList<Column> columns = new List<Column>();
            string[] columnFiles = Directory.GetFiles("databases//" + databaseId.ToString() + "//" + tableId.ToString());

            foreach (string columnFile in columnFiles)
            {
                if (columnFile.Contains("C"))
                {
                    Stream stream = File.Open(columnFile, FileMode.Open);
                    BinaryFormatter bformatter = new BinaryFormatter();
                    Column column = (Column)bformatter.Deserialize(stream);
                    stream.Close();

                    columns.Add(column);
                }
            }

            int temp = Int32.Parse(columnId);

            foreach (Column column in columns)
            {
                if (column.Index == temp)
                {
                    column.Deleted = true;

                    string colPath = "databases//" + databaseId + "//" + tableId + "//C" + column.Index;

                    Stream stream = File.Open(colPath, FileMode.Truncate);
                    BinaryFormatter bformatter = new BinaryFormatter();
                    bformatter.Serialize(stream, column);
                    stream.Close();
                }

                
            }
        }
    }
}
